"""
回测买卖配对算法
测试算法在真实历史数据上的表现
"""
import sys
sys.path.append('.')

from api.stock_api import StockAPIClient
from analysis.signal_generator import SignalGenerator
from datetime import datetime
from typing import List, Dict

class BacktestResult:
    """回测结果"""
    def __init__(self):
        self.trades = []  # 交易记录
        self.total_trades = 0  # 总交易次数
        self.winning_trades = 0  # 盈利次数
        self.losing_trades = 0  # 亏损次数
        self.total_profit = 0.0  # 总盈利率
        self.max_profit = 0.0  # 单笔最大盈利
        self.max_loss = 0.0  # 单笔最大亏损
        self.win_rate = 0.0  # 胜率
        self.avg_profit = 0.0  # 平均盈利率
        self.avg_win = 0.0  # 平均盈利（盈利交易）
        self.avg_loss = 0.0  # 平均亏损（亏损交易）

def backtest_stock(symbol: str, stock_name: str) -> BacktestResult:
    """回测单个股票"""
    print(f"\n{'='*70}")
    print(f"📊 回测股票: {symbol} - {stock_name}")
    print('='*70)
    
    # 获取数据
    client = StockAPIClient()
    signal_gen = SignalGenerator()
    
    # 获取更多历史数据用于回测（180天）
    history = client.get_history_data(symbol, 180)
    
    if not history or len(history) < 30:
        print(f"❌ 数据不足: {len(history) if history else 0} 条")
        return None
    
    print(f"✅ 获取 {len(history)} 条历史数据")
    first_date = datetime.fromtimestamp(history[0]['timestamp'] / 1000).strftime('%Y-%m-%d')
    last_date = datetime.fromtimestamp(history[-1]['timestamp'] / 1000).strftime('%Y-%m-%d')
    print(f"📅 数据范围: {first_date} 到 {last_date}")
    
    # 识别买卖点
    trading_points = signal_gen.identify_trading_points(history)
    
    if not trading_points:
        print("⚠️  没有识别到交易点")
        return None
    
    # 分析交易对
    result = BacktestResult()
    buy_points = [p for p in trading_points if p['type'] == 'BUY']
    sell_points = [p for p in trading_points if p['type'] == 'SELL']
    
    print(f"\n📈 识别到 {len(buy_points)} 个买入点")
    print(f"📉 识别到 {len(sell_points)} 个卖出点")
    
    # 配对分析
    print(f"\n{'='*70}")
    print("💰 交易记录")
    print('='*70)
    
    for i, (buy, sell) in enumerate(zip(buy_points, sell_points), 1):
        buy_date = datetime.fromtimestamp(buy['timestamp'] / 1000).strftime('%Y-%m-%d')
        sell_date = datetime.fromtimestamp(sell['timestamp'] / 1000).strftime('%Y-%m-%d')
        buy_price = buy['price']
        sell_price = sell['price']
        profit_rate = (sell_price - buy_price) / buy_price * 100
        
        result.trades.append({
            'buy_date': buy_date,
            'sell_date': sell_date,
            'buy_price': buy_price,
            'sell_price': sell_price,
            'profit_rate': profit_rate,
            'buy_reason': buy.get('reason', ''),
            'sell_reason': sell.get('reason', '')
        })
        
        result.total_trades += 1
        result.total_profit += profit_rate
        
        if profit_rate > 0:
            result.winning_trades += 1
            result.avg_win += profit_rate
            result.max_profit = max(result.max_profit, profit_rate)
            status = "✅ 盈利"
        else:
            result.losing_trades += 1
            result.avg_loss += profit_rate
            result.max_loss = min(result.max_loss, profit_rate)
            status = "❌ 亏损"
        
        print(f"\n交易 #{i} {status}")
        print(f"  买入: {buy_date} ¥{buy_price:.2f}")
        print(f"  卖出: {sell_date} ¥{sell_price:.2f}")
        print(f"  盈利: {profit_rate:+.2f}%")
        print(f"  原因: {sell.get('reason', '')}")
    
    # 计算统计指标
    if result.total_trades > 0:
        result.win_rate = (result.winning_trades / result.total_trades) * 100
        result.avg_profit = result.total_profit / result.total_trades
        
        if result.winning_trades > 0:
            result.avg_win = result.avg_win / result.winning_trades
        
        if result.losing_trades > 0:
            result.avg_loss = result.avg_loss / result.losing_trades
    
    return result

def print_summary(results: Dict[str, BacktestResult]):
    """打印汇总结果"""
    print(f"\n\n{'='*70}")
    print("📊 回测汇总报告")
    print('='*70)
    
    total_trades = 0
    total_wins = 0
    total_profit = 0.0
    max_profit_overall = 0.0
    max_loss_overall = 0.0
    
    for symbol, result in results.items():
        if result:
            total_trades += result.total_trades
            total_wins += result.winning_trades
            total_profit += result.total_profit
            max_profit_overall = max(max_profit_overall, result.max_profit)
            max_loss_overall = min(max_loss_overall, result.max_loss)
    
    print(f"\n总交易次数: {total_trades}")
    print(f"盈利次数: {total_wins}")
    print(f"亏损次数: {total_trades - total_wins}")
    print(f"\n✨ 整体胜率: {(total_wins/total_trades*100) if total_trades > 0 else 0:.2f}%")
    print(f"📈 累计盈利: {total_profit:.2f}%")
    print(f"📊 平均盈利: {(total_profit/total_trades) if total_trades > 0 else 0:.2f}%")
    print(f"🎯 单笔最大盈利: {max_profit_overall:.2f}%")
    print(f"⚠️  单笔最大亏损: {max_loss_overall:.2f}%")
    
    print(f"\n{'='*70}")
    print("📋 各股票详细表现")
    print('='*70)
    
    for symbol, result in results.items():
        if result and result.total_trades > 0:
            print(f"\n{symbol}:")
            print(f"  交易次数: {result.total_trades}")
            print(f"  胜率: {result.win_rate:.2f}%")
            print(f"  平均盈利: {result.avg_profit:+.2f}%")
            print(f"  盈利交易平均: {result.avg_win:+.2f}%")
            print(f"  亏损交易平均: {result.avg_loss:+.2f}%")

def main():
    """主函数"""
    print("\n" + "="*70)
    print("🎯 买卖配对算法回测系统")
    print("="*70)
    print("\n算法参数:")
    print("  ✅ 目标止盈: 5%")
    print("  ✅ 回撤止盈: 3%")
    print("  ✅ 止损线: -5%")
    print("  ✅ 技术止盈: 盈利>3%时")
    
    # 测试股票列表
    test_stocks = [
        ("sh600519", "贵州茅台"),
        ("sz000858", "五粮液"),
        ("sh601318", "中国平安"),
        ("sh600036", "招商银行"),
        ("sz000651", "格力电器"),
    ]
    
    results = {}
    
    for symbol, name in test_stocks:
        try:
            result = backtest_stock(symbol, name)
            results[f"{symbol}-{name}"] = result
        except Exception as e:
            print(f"❌ 回测失败: {e}")
            import traceback
            traceback.print_exc()
    
    # 打印汇总
    print_summary(results)
    
    print(f"\n{'='*70}")
    print(f"⏰ 回测完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print('='*70 + "\n")

if __name__ == "__main__":
    main()

